home *** CD-ROM | disk | FTP | other *** search
- page 60,132
- ; Program to let SuperCalc 3, Lotus 123 1A and others
- ; that may have problems successfully use Hercules
- ; emulation on the Equity II.
- ; Since this program remains resident, it is run only
- ; once, and need not be run until the Equity II is
- ; powered down or reset.
- ; It is recommended that this program be the last resident
- ; program in memory.
-
- ; DOS definitions
- dos equ 21h ;dos interrupt
- term_res equ 31h ;terminate but stay resident
- terminate equ 4ch ;terminate process
- set_vector equ 25h ;set interrupt vector
- get_vector equ 35h ;get interrupt vector
- display_str equ 09 ;display string
- ; Interrupt numbers
- video_int equ 10h
- ; Control characters
- cr equ 0dh
- lf equ 0ah
-
- code segment para 'CODE'
-
- assume cs:code,ds:nothing,es:nothing,ss:nothing
- org 100h
-
- begin: jmp short start
-
- modeherc proc far
-
- new_video_int: ;BIOS video (INT 10H) is redirected here.
- ;Check to see if user program is requesting
- ;set mono mode (AH=0, AL=7).
-
- cmp ah,0 ;set video mode?
- jnz go_vid ;no, just continue
- cmp al,7 ;set mono mode?
- jnz go_vid ;if not, goto video int
- pushf ;set up for IRET from vid int
- push cs ;same
- mov word ptr cs:ax_save,ax ;save temporarily
- mov ax,offset continue ;get continuation address
- push ax ;save it for IRET from video
- mov ax,word ptr cs:ax_save ;restore user's AX
- go_vid: jmp dword ptr cs:old_video_int_off ;go to real int 10h
-
- continue:
- push dx
- push ax
- mov dx,03bfh ;hercules configuration port
- mov al,03 ;graphics and page 1 can be used now
- out dx,al ;set it
- pop ax
- pop dx
- iret ;back to user
-
- sig_offset equ $ - new_video_int
- res_sig: db 'Modeherc'
- sig_len equ $ - res_sig
-
- ax_save: dw ?
- return_off: dw ?
- return_seg: dw ?
-
- old_video_int_off: dw ?
- old_video_int_seg: dw ?
- last equ $-1 ;mark end of resident code
- modeherc endp
-
- assume ds:code
- start proc near ;redirect video int to point to
- ;new_video_int and save current vector
-
- mov sp,offset stack
- call chk_res ;see if we're resident already
- ;returns interrupt address in ES:BX
-
- mov word ptr old_video_int_off,bx ;store offset
- mov word ptr old_video_int_seg,es ;store segment
-
- mov dx,offset new_video_int ;DS:DX is now new int address
- mov al,video_int ;video interrupt #
- mov ah,set_vector ;set vector func
- int dos ;set int 10h to new_video_int
-
- mov ax,7 ;reset mono mode before
- int 10h ;leaving so hercules is in full mode
-
- mov dx,offset last ;byte count of code to stay resident
- mov cl,4
- shr dx,cl ;change to paragraph count
- inc dx ;just to be sure
- mov ah,term_res
- mov al,0 ;return code of 0
- int dos ;that's all folks
- start endp
-
- chk_res proc near ;check if modeherc routine resident
- ;if not, returns current video interrupt
- ;in ES:BX
- mov ah,get_vector
- mov al,video_int ;video interrupt
- int dos ;get video interrupt vector in es:bx
- mov di,sig_offset ;offset of signature bytes from int offset
- add di,bx ;add in interrupt offset
- mov si,offset res_sig ;point to sig bytes
- mov cx,sig_len ;length of sig
- cld
- repz cmpsb ;is it there?
- jz its_there
- ret ;back to main program
-
- its_there: ;print already resident message
- pop ax
- pop ax
- pop ax ;clean up stack
-
- mov dx,offset there_mes
- mov ah,display_str
- int dos ;display message
- mov ah,terminate ;normal end of process
- mov al,0
- int dos ;back to calling process
-
- there_mes:
- db cr,lf,'Already resident ...',cr,lf,'$'
- chk_res endp
-
- stk: db 16 dup('STACK...')
- stack label word
- code ends
- end begin